﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using EnvDTE80;
using EnvDTE;
using System.Linq;
using Microsoft.VisualStudio.ExtensionManager;
using FunctionPoint;
using FunctionPoint.Services;
using FunctionPoint.UI;
using FCommon = FunctionPoint.Common;
namespace SiAAS.FunctionPointVSPackage
{
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 5339)]
    [ProvideMenuResource("Menus.ctmenu", 1)]
    [ProvideToolWindow(typeof(FunctionPointExplorerTreeControlHost))]
    [ProvideToolWindow(typeof(FunctionPointSelectorToolWindowHost))]
    [ProvideService(typeof(SFunctionPointManagerService))]
    [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
    [ProvideAutoLoad(VSConstants.UICONTEXT.CodeWindow_string)]
    [ProvideOptionPage(typeof(FunctionPointGeneralOptionsPage),"Team Options", FunctionPoint.Common.Constants.OPTIONSPAGE_PAGENAME,200,201, true)]
    [ProvideProfile(typeof(FunctionPointGeneralOptionsPage), FunctionPoint.Common.Constants.OPTIONSPAGE_PAGENAME, FunctionPoint.Common.Constants.OPTIONSPAGE_DESIGNERGROUPFIELDNAME, 201, 202, true, DescriptionResourceID = 203)]
    [Guid(GuidList.guidFunctionPointVSPackagePkgString)]
    public sealed class FunctionPointVSPackagePackage : Package, IVsPersistSolutionProps
    {


       
        // swithced to singleton because I was just wasting resources and causing lots of confusion.  
        // Think cJ... Think..
        private FunctionPointManagerService singletonServiceInstance = null;
        public FunctionPointVSPackagePackage()
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));

            // http://msdn.microsoft.com/en-us/library/bb164693.aspx

            IServiceContainer serviceContainer = this as IServiceContainer;
            serviceContainer.AddService(typeof(SFunctionPointManagerService), new ServiceCreatorCallback((container, serviceType) =>
            {

                if (typeof(SFunctionPointManagerService) == serviceType)
                {
                    if (singletonServiceInstance == null)
                        singletonServiceInstance = new FunctionPointManagerService(this);

                    return singletonServiceInstance;
                }
                return null;
            }), true);


        }

        #region Tool window callbacks
        private void ShowFunctionPointExplorerToolWindow(object sender, EventArgs e)
        {
            // Get the instance number 0 of this tool window. This window is single instance so this instance
            // is actually the only one.
            // The last flag is set to true so that if the tool window does not exists it will be created.
            ToolWindowPane window = this.FindToolWindow(typeof(FunctionPointExplorerTreeControlHost), 0, true);
            if ((null == window) || (null == window.Frame))
            {
                throw new NotSupportedException(Resources.CanNotCreateWindow);
            }
            IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;



            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        private void ShowFunctionPointSelectorToolWindow(object sender, EventArgs e)
        {
            ToolWindowPane window = this.FindToolWindow(typeof(FunctionPointSelectorToolWindowHost), 0, true);

            if ((null == window) || (null == window.Frame))
            {
                throw new NotSupportedException(Resources.CanNotCreateWindow);
            }
            IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
            FunctionPointSelectorToolWindowHost windowhost = (FunctionPointSelectorToolWindowHost)window;

            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }
        #endregion

        #region Package Members

        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initilaization code  that rely on services provided by VisualStudio.
        /// </summary>
        protected override void Initialize()
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
            base.Initialize();

            // Add our command handlers for menu (commands must exist in the .vsct file)
            OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            if (null != mcs)
            {
                // Create the command for the tool window
                CommandID toolwndCommandID = new CommandID(GuidList.guidFunctionPointVSPackageCmdSet, (int)PkgCmdIDList.cmdidFunctionPointExplorerToolWindow);
                MenuCommand menuToolWin = new MenuCommand(ShowFunctionPointExplorerToolWindow, toolwndCommandID);
                mcs.AddCommand(menuToolWin);

                // Command for the selector window (show multiple adornments for multiple function points on a single editor

                CommandID selectorToolwndCommandId = new CommandID(GuidList.guidFunctionPointVSPackageCmdSet, (int)PkgCmdIDList.cmdidFunctionPointSelectorToolWindow);
                MenuCommand menuSelectorToolWin = new MenuCommand(ShowFunctionPointSelectorToolWindow, selectorToolwndCommandId);
                mcs.AddCommand(menuSelectorToolWin);

            }


        }




        #endregion
        #region IVsPersistSolutionProps

        private string _designGroupName;
        private string _engineeringGroupName;
        private string _qaGroupName;
        private string _businessAnalystGroupName;

        public string DesignGroupName
        {
            get
            {
                return _designGroupName;
            }
            set
            {
                _designGroupName = value;
                IsDirty = true;
            }
        }
        public string EngineeringGroupName
        {
            get
            {
                return _engineeringGroupName;
            }
            set
            {
                _engineeringGroupName = value;
                IsDirty = true;

            }
        }
        public string QAGroupName
        {
            get
            {
                return _qaGroupName;
            }
            set
            {
                _qaGroupName = value;
                IsDirty = true;
            }
        }

        public string BusinessAnalystGroupName
        {
            get
            {
                return _businessAnalystGroupName;
            }
            set
            {
                _businessAnalystGroupName = value;
                IsDirty = true;
            }
        }

        private bool IsDirty { get; set; }




        public int LoadUserOptions(IVsSolutionPersistence pPersistence, uint grfLoadOpts)
        {
            return VSConstants.S_OK;
        }

        public int OnProjectLoadFailure(IVsHierarchy pStubHierarchy, string pszProjectName, string pszProjectMk, string pszKey)
        {
            return VSConstants.S_OK;
        }

        public int QuerySaveSolutionProps(IVsHierarchy pHierarchy, VSQUERYSAVESLNPROPS[] pqsspSave)
        {
            //Debug.WriteLine("Entering QuerySaveSolutionProps");
                                    

            if (IsDirty)
                return (int)VSQUERYSAVESLNPROPS.QSP_HasDirtyProps;
            else
                return (int)VSQUERYSAVESLNPROPS.QSP_HasNoDirtyProps;

        }

        public int ReadSolutionProps(IVsHierarchy pHierarchy, string pszProjectName, string pszProjectMk, string pszKey, int fPreLoad, Microsoft.VisualStudio.OLE.Interop.IPropertyBag pPropBag)
        {

            Debug.WriteLine("Entering ReadSolutionProps");

            if (FCommon.Constants.SOLUTIONPROP_GLOBALSECTIONNAME.CompareTo(pszKey) == 0)
            {
                object pVar = null;
                pPropBag.Read(FCommon.Constants.SOLUTIONPROP_DESIGNGROUPPROPERTYNAME, out pVar, null, 0, null);

                if (pVar != null && pVar.ToString().Length > 0)
                    DesignGroupName = pVar.ToString();
                else
                    DesignGroupName = FCommon.Constants.SOLUTIONPROP_DESIGNGROUPPROPERTYNAME_DEFAULTVALUE;


                pPropBag.Read(FCommon.Constants.SOLUTIONPROP_CODERGROUPPROPERTYNAME, out pVar, null, 0, null);
                if (pVar != null && pVar.ToString().Length > 0)
                    EngineeringGroupName = pVar.ToString();
                else
                    EngineeringGroupName = FCommon.Constants.SOLUTIONPROP_CODERGROUPPROPERTYNAME_DEFAULTVALUE;

            }
            return VSConstants.S_OK;
        }

        public int ReadUserOptions(Microsoft.VisualStudio.OLE.Interop.IStream pOptionsStream, string pszKey)
        {
            Debug.WriteLine("Entering ReadUserOptions");
            return VSConstants.S_OK;
        }

        public int SaveSolutionProps(IVsHierarchy pHierarchy, IVsSolutionPersistence pPersistence)
        {
            Debug.WriteLine("Entering SaveSolutionProps");

            // pHierarchy isn't important here because we want it at the global level
            int returnValue =
                pPersistence.SavePackageSolutionProps(VSConstants.S_FALSE, null, (IVsPersistSolutionProps)this, FCommon.Constants.SOLUTIONPROP_GLOBALSECTIONNAME);

            Debug.WriteLine("SaveSolutionProps Return Value", new object[] { returnValue });

            return returnValue;

            //return VSConstants.S_OK;
        }

        public int SaveUserOptions(IVsSolutionPersistence pPersistence)
        {
            return VSConstants.S_OK;
        }

        public int WriteSolutionProps(IVsHierarchy pHierarchy, string pszKey, Microsoft.VisualStudio.OLE.Interop.IPropertyBag pPropBag)
        {
            Debug.WriteLine("Entering WriteSolutionProps");

            object pVar;

            if (DesignGroupName.Length > 0)
                pVar = DesignGroupName;
            else
                pVar = FCommon.Constants.SOLUTIONPROP_DESIGNGROUPPROPERTYNAME_DEFAULTVALUE;

            pPropBag.Write(FCommon.Constants.SOLUTIONPROP_DESIGNGROUPPROPERTYNAME, ref pVar);

            if (EngineeringGroupName.Length > 0)
                pVar = EngineeringGroupName;
            else
                pVar = FCommon.Constants.SOLUTIONPROP_CODERGROUPPROPERTYNAME_DEFAULTVALUE;

            pPropBag.Write(FCommon.Constants.SOLUTIONPROP_CODERGROUPPROPERTYNAME, ref pVar);

            return VSConstants.S_OK;
        }

        public int WriteUserOptions(Microsoft.VisualStudio.OLE.Interop.IStream pOptionsStream, string pszKey)
        {
            return VSConstants.S_OK;
        }
        #endregion
    }
}
